#include <47func.h>
typedef struct train_s {
    int length;
    char data[1000];//上限是1000个字节
}train_t;
//int recvFile(int sockfd){
//    // 先收文件名
//    //char filename[1024] = {0};
//    //recv(sockfd,filename,sizeof(filename),0);
//    //int fd = open(filename,O_RDWR|O_CREAT,0666);
//    //char buf[4096] = {0};
//    //ssize_t sret = recv(sockfd,buf,sizeof(buf),0);
//    //write(fd,buf,sret);
//    //close(fd);
//    train_t train;
//    bzero(&train,sizeof(train));
//    recv(sockfd,&train.length,sizeof(train.length),0);//先收四个字节
//    recv(sockfd,train.data,train.length,0);//再一个train.length的长度
//    int fd = open(train.data,O_RDWR|O_CREAT,0666);
//    bzero(&train,sizeof(train));
//    recv(sockfd,&train.length,sizeof(train.length),0);//先收四个字节
//    recv(sockfd,train.data,train.length,0);//再一个train.length的长度
//    write(fd,train.data,train.length);
//    close(fd);
//    return 0;
//}
int recvn(int sockfd, void *buf, int length){
    int total = 0;
    int ret;
    char *p = (char *)buf;
    while(total < length){
        ret = recv(sockfd,p+total,length-total,0);
        total += ret;
    }
    return 0;
}
//int recvFile(int sockfd){
//    // 先收文件名
//    train_t train;
//    bzero(&train,sizeof(train));
//    //recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);//先收四个字节
//    //recv(sockfd,train.data,train.length,MSG_WAITALL);//再一个train.length的长度
//    recvn(sockfd,&train.length,sizeof(train.length));
//    recvn(sockfd,train.data,train.length);
//    int fd = open(train.data,O_RDWR|O_CREAT,0666);
//    while(1){
//        bzero(&train,sizeof(train));
//        //recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);//先收四个字节
//        recvn(sockfd,&train.length,sizeof(train.length));//先收四个字节
//        if(train.length != 1000){
//            printf("train.length = %d\n",train.length);
//        }
//        if(train.length == 0){
//            break;
//        }
//        //recv(sockfd,train.data,train.length,MSG_WAITALL);//再一个train.length的长度
//        recvn(sockfd,train.data,train.length);//再一个train.length的长度
//        write(fd,train.data,train.length);
//    }
//    close(fd);
//    return 0;
//}
int recvFile(int sockfd){
    // 先收文件名
    train_t train;
    bzero(&train,sizeof(train));
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    int fd = open(train.data,O_RDWR|O_CREAT,0666);
    off_t filesize;
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,&filesize,train.length);
    printf("filesize = %ld\n", filesize);
    off_t cursize = 0;
    off_t lastsize = 0;
    off_t slice = filesize/10000;
    while(1){
        bzero(&train,sizeof(train));
        //recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);//先收四个字节
        recvn(sockfd,&train.length,sizeof(train.length));//先收四个字节
        if(train.length != 1000){
            printf("train.length = %d\n",train.length);
        }
        if(train.length == 0){
            break;
        }
        //recv(sockfd,train.data,train.length,MSG_WAITALL);//再一个train.length的长度
        recvn(sockfd,train.data,train.length);//再一个train.length的长度
        write(fd,train.data,train.length);
        cursize += train.length;
        if(cursize - lastsize > slice ){
            printf("%5.2lf%%\r",100.0*cursize/filesize);
            fflush(stdout);
            lastsize = cursize;
        }
    }
    printf("100.00%%\n");
    close(fd);
    return 0;
}
//int recvFile(int sockfd){
//    // 先收文件名
//    train_t train;
//    bzero(&train,sizeof(train));
//    recvn(sockfd,&train.length,sizeof(train.length));
//    recvn(sockfd,train.data,train.length);
//    int fd = open(train.data,O_RDWR|O_CREAT,0666);
//    off_t filesize;
//    recvn(sockfd,&train.length,sizeof(train.length));
//    recvn(sockfd,&filesize,train.length);
//    printf("filesize = %ld\n", filesize);
//    // 建立映射区
//    ftruncate(fd,filesize);
//    char *p = (char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
//    ERROR_CHECK(p,MAP_FAILED,"mmap");
//    recvn(sockfd,p,filesize);
//    munmap(p,filesize);
//    close(fd);
//    return 0;
//}
int main(int argc, char *argv[])
{
    // ./client 192.168.118.128 1234
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    serverAddr.sin_port = htons(atoi(argv[2]));
    int ret = connect(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"connect");
    recvFile(sockfd);
    return 0;
}

